import { StrUtils } from "./str"

export namespace BrowserUtils {
    export function getUrlFromCanvas(canvas: HTMLCanvasElement) {
        try {
            return canvas.toDataURL('image/png')
        } catch (error) {
            return ''
        }
    }
    export function getResourceSuffix(res: ResourceInfo) {
        if (res.type === 'canvas') {
            return '.png'
        } else if (res.type === 'image') {
            if (res.name.includes('.jpg') || res.name.includes('.jpeg')) {
                return '.jpg'
            } else if (res.name.includes('svg')) {
                return '.svg'
            } else {
                return '.png'
            }
        } else if (res.type === 'media') {
            const matchAudio = res.name.match(/.(mp3|wav|ogg|m4a|aac)/)
            const matchVideo = res.name.match(/.(mp4|webm)/)
            if (matchAudio) {
                return matchAudio[0]
            } else if (matchVideo) {
                return matchVideo[0]
            } else {
                return '.mp4'
            }
        } else if (res.type === 'script') {
            return '.js'
        } else if (res.type === 'stylesheet') {
            return '.css'
        } else if (res.type === 'font') {
            return '.ttf'
        } else if (res.type === '3dmodle') {
            const match = res.name.match(/.(glb|gltf|fbx|obj|stl|ply|dae)/)
            if (match) {
                return match[0]
            } else {
                return '.glb'
            }
        } else {
            return ''
        }
    }
    export async function getResources(t?: ResourceInfoType) {
        const res: ResourceInfo[] = []
        //img
        const imgs = document.getElementsByTagName('img')
        const imgsRes: ResourceInfo[] = Array.from(imgs).map((img) => {
            return {
                name: StrUtils.getNameFromUrl(img.src),
                url: img.src,
                type: 'image',
                size: 0
            }
        })
        res.push(...imgsRes)
        //svg
        const svg = document.getElementsByTagName('svg')
        const svgRes: ResourceInfo[] = Array.from(svg).map((item, index) => {
            return {
                name: 'svg-' + index,
                url: URL.createObjectURL(new Blob([item.outerHTML], { type: 'image/svg+xml' })),
                type: 'image',
                size: 0
            }
        })
        res.push(...svgRes)

        //video
        const video = document.getElementsByTagName('video')
        const videoRes: ResourceInfo[] = Array.from(video).map((item) => {
            const res: ResourceInfo = {
                name: (item.src ? StrUtils.getNameFromUrl(item.src) : 'inactive video'),
                url: item.src,
                type: 'media',
            }
            if (!res.url) {
                const source = item.querySelector('source')
                if (source) {
                    res.url = source.src
                    res.name = StrUtils.getNameFromUrl(source.src)
                }
            }
            return res
        })

        res.push(...videoRes)

        //canvas
        const canvas = document.getElementsByTagName('canvas')
        const canvasRes: ResourceInfo[] = Array.from(canvas).map((item, index) => {
            return {
                name: 'canvas-' + index,
                url: BrowserUtils.getUrlFromCanvas(item),
                type: 'canvas',
                size: 0
            }
        })
        res.push(...canvasRes)

        //audio
        const audio = document.getElementsByTagName('audio')
        const audioRes: ResourceInfo[] = Array.from(audio).map((item) => {
            const res: ResourceInfo = {
                name: StrUtils.getNameFromUrl(item.src),
                url: item.src,
                type: 'media',
            }
            if (!res.url) {
                const source = item.querySelector('source')
                if (source) {
                    res.url = source.src
                    res.name = StrUtils.getNameFromUrl(source.src)
                }
            }
            return res
        })
        res.push(...audioRes)

        // 去重
        const urls = res.map(item => item.url)
        const temp = new Set(urls)
        const newres = Array.from(temp).map(url => res.find(item => item.url === url))

        return newres.map(item => {
            if (item) {
                item.name += getResourceSuffix(item)
            }
            return item
        }).filter(item => item && (t ? item.type === t : true))
    }

    export async function openFile<T>(text = false): Promise<T> {
        return new Promise((resolve) => {
            const input = document.createElement('input');
            input.style.display = 'none';
            input.type = 'file';
            document.body.appendChild(input);
            input.onchange = () => {
                const file = input.files?.[0];
                if (!file) {
                    input.remove();
                    resolve(undefined as T);
                    return;
                }
                if (!text) {
                    resolve(file as T)
                }
                const reader = new FileReader();
                reader.onload = () => {
                    resolve(reader.result as T);
                };
                reader.readAsText(file);
                input.remove();
            };
            input.click();
        })
    }

    export function loadImage(url: string) {
        return new Promise<HTMLImageElement>((resolve, reject) => {
            const img = new Image();
            img.onload = () => {
                resolve(img);
            };
            img.onerror = () => {
                reject(new Error('Failed to load image'));
            };
            img.src = url;
        });
    }

    export function download(url: string, filename?: string) {
        if (!url) {
            throw Error('No url')
        }
        const a = document.createElement('a');
        a.href = url;
        a.download = filename || 'download';
        a.style.display = 'none';
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
    }

    export function downloadWithData(data:any,filename:string,type:string='text/txt'){
        
        let b:Blob
        if(typeof data ==='string'){
            b = new Blob([data],{type})
        }else{
            b = new Blob([JSON.stringify(data)],{type})
        }
        if(!chrome.downloads){
            console.log(data)
            console.log('not suport')
            return
        }
        chrome.downloads.download({
            url:URL.createObjectURL(b),
            filename,
            saveAs: true
        });
    }

    export function readFile(file: File, type = 'text'): Promise<any> {
        return new Promise((resolve, reject) => {
            const reader = new FileReader()
            reader.onload = () => {
                resolve(reader.result)
            }
            reader.onerror = (error) => {
                reject(error)
            }
            if (type === 'arraybuffer') {
                reader.readAsArrayBuffer(file)
            } else if (type === 'base64') {
                reader.readAsDataURL(file)
            } else {
                reader.readAsText(file)
            }
        })
    }
}